#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <time.h>
#include "common.h"
#include <openssl/md5.h>
#include <sqlite3.h>
#include <arpa/inet.h>

//全局变量
int g_register = 0;
int g_login = 0;
char g_uuid[32] = {0};
char g_passwd[32] = {0};

/********************************************************************
 *函数名：int recv_msg(int sockfd,char *buf,int size)
 *功能：接收信息
 *参数：
 * sockfd:网络套接字 
 * buf:接收到的数据
 * size:数据大小
 *返回值：成功返回0，失败返回-1
 ********************************************************************/
int recv_msg(int sockfd,char *buf)
{
	int ret;
	msghead_t head;
	int dataSize;

	ret = recv(sockfd,buf,sizeof(head),0);
	if(ret <= 0)
	{
		if(ret == 0)
			printf("Connection closed\n");
		else
			perror("recv msghead failed");
		return -1;
	}

	memcpy(&head,buf,sizeof(head));
	dataSize = ntohl(head.datasize);
	if (dataSize == 0) {
		return 0;
	}

	ret = recv(sockfd,buf+sizeof(head),dataSize,0);
	if(ret <= 0)
	{
		if(ret == 0)
			printf("Connection closed\n");
		else
			perror("recv msgbody failed");
		return -1;
	}

	return 0;
}

/********************************************************************
 *函数名：int send_msg(int sockfd,char msgType,char dataType,void *data,int size)
 *功能：发送信息
 *参数:
 * sockfd:网络套接字 
 * msgType:消息类型
 * dataType:数据类型
 * sequence:序列号
 * data:要发送的数据
 * size:数据大小
 *返回值：成功返回0，失败返回-1
********************************************************************/
int send_msg(int sockfd,char msgType,char dataType,void *data,int size)
{
	static unsigned int Sequence = 0;
	if(Sequence == 0)
		Sequence = rand();
	msghead_t head;
	int ret;
	char buf[256] = {0};
	memset(&head,0,sizeof(head));
	memcpy(head.magic, MAGIC, 4);
	head.version = MSGVERSION;
	head.msgtype = msgType;
	head.datatype = dataType;
	head.resv = RESV;
	head.timestamp = htonl((unsigned int)time(NULL));
	if(msgType == HEARTBEAT)
	{
		head.sequence = htonl(0);
	}
	else 
		head.sequence = htonl(Sequence++);
	head.datasize = htonl(size);

	memcpy(&buf,&head,sizeof(head));

	if(data && size > 0)
	{
		memcpy(buf+sizeof(head),data,size);
	}

	ret = send(sockfd,buf,sizeof(head)+size,0);
	if(ret < 0)
	{
		perror("send failed");
		return -1;
	}
	return 0;
}

/********************************************************************
 *函数名：int server_process_msg(int sockfd,char *buf)
 *功能：服务端处理消息
 *参数:
 * sockfd:网络套接字 
 * buf:要处理的数据
 *返回值：成功返回0，失败返回-1
********************************************************************/
int server_process_msg(int sockfd,char *buf)
{
	msghead_t head;
	memcpy(&head,buf,sizeof(head));

	char msgtype = head.msgtype;
	char datatype = head.datatype;
	int ret;

	switch(msgtype)
	{
		case HEARTBEAT:
		{
			printf("Received client heartbeat\n");
			printf("device is online\n");
			break;
		}
		case REQUEST:
		{
			switch(datatype)
			{
				case REGISTER:
				{
					register_request_t reg;
					memset(&reg,0,sizeof(reg));
					memcpy(&reg,buf+sizeof(head),sizeof(reg));

					char uuid[32] = {0};
					char passwd[16] = {0};
					register_response_t reg_data;
					ret = register_handler(&reg,uuid,passwd);
					if(ret == 0)
					{
						memcpy(reg_data.uuid,uuid,sizeof(reg_data.uuid));
						memcpy(reg_data.passwd,passwd,sizeof(reg_data.passwd));
					}
					msgresp_t reg_resp;
					reg_resp.result = ret;
					strcpy(reg_resp.desc,(ret == 0)?"Success":"Failed");
					memcpy(reg_resp.data,&reg_data,sizeof(reg_data));
					send_msg(sockfd,RESPONSE,REGISTER,&reg_resp,sizeof(reg_resp));
					break;
				}
				case LOGIN:
				{
					login_request_t log;
					memset(&log,0,sizeof(log));
					memcpy(&log,buf+sizeof(head),sizeof(log));
					ret = login_handler(&log);
					msgresp_t log_resp;
					log_resp.result = ret;
					strcpy(log_resp.desc,(ret == 0)?"Success":"Failed");
					send_msg(sockfd,RESPONSE,LOGIN,&log_resp,sizeof(log_resp));
					if(ret == 0) {
						distribute_all_persons();
					}
					break;
				}
				case ADDPERSON:
				{
					add_person_request_t add;
					memset(&add,0,sizeof(add));
					memcpy(&add,buf+sizeof(head),sizeof(add));
					send_msg(sockfd,REQUEST,ADDPERSON,&add,sizeof(add));
					break;
				}
				case UPDATEPERSON:
				{
					update_person_request_t upd;
					memset(&upd,0,sizeof(upd));
					memcpy(&upd,buf+sizeof(head),sizeof(upd));
					send_msg(sockfd,REQUEST,UPDATEPERSON,&upd,sizeof(upd));
					break;
				}
				case DELPERSON:
				{
					delete_person_request_t del;
					memset(&del,0,sizeof(del));
					memcpy(&del,buf+sizeof(head),sizeof(del));
					send_msg(sockfd,REQUEST,DELPERSON,&del,sizeof(del));
					break;
				}
				case CLRPERSON:
				{
					send_msg(sockfd,REQUEST,CLRPERSON,NULL,0);
					break;
				}

				default:
				{
					printf("invalid request datatype,try again!\n");
					break;
				}
			}
			break;
		}
		case RESPONSE:
		{
			switch(datatype)
			{
			case ADDPERSON:
				{
					msgresp_t resp;
					memcpy(&resp, buf+sizeof(head), sizeof(resp));
					if(resp.result == 0) {
						printf("Add person successful\n");
					}else
						printf("Add person failed\n");
					break;
				}
			case UPDATEPERSON:
				{
					msgresp_t resp;
					memcpy(&resp, buf+sizeof(head), sizeof(resp));
					if(resp.result == 0) {
						printf("Update person successful\n");
					}else
						printf("Update person failed\n");
					break;
				}
			case DELPERSON:
				{
					msgresp_t resp;
					memcpy(&resp, buf+sizeof(head), sizeof(resp));
					if(resp.result == 0) {
						printf("Delete person successful\n");
					}else
						printf("Delete person failed\n");
					break;
				}
			case CLRPERSON:
				{
					msgresp_t resp;
					memcpy(&resp, buf+sizeof(head), sizeof(resp));
					if(resp.result == 0) {
						printf("Clear person successful\n");
					}else
						printf("Clear person failed\n");
					break;
				}
			default:
				{
					printf("invalid response datatype,try again!\n");
					break;
				}
			}
			break;
		}
		default:
		{
			printf("invalid client msgtype,try again!\n");
			break;
		}
	}
	return 0;
}

/********************************************************************
 *函数名：int client_process_msg(int sockfd,char *buf)
 *功能：客户端处理消息
 *参数:
 * sockfd:网络套接字 
 * buf:要处理的数据
 *返回值：成功返回0，失败返回-1
********************************************************************/
int client_process_msg(int sockfd,char *buf)
{
	int ret = 0;
	msghead_t head;
	memcpy(&head,buf,sizeof(head));

	char msgtype = head.msgtype;
	char datatype = head.datatype;

	switch(msgtype)
	{
		case HEARTBEAT:
		{
			printf("invalid message!\n");
			break;
		}
		case REQUEST:
		{
			switch(datatype)
			{
			case ADDPERSON:
				{
					add_person_request_t add;
					memset(&add,0,sizeof(add));
					memcpy(&add,buf+sizeof(head),sizeof(add));
					ret = add_person_handler(&add);
					msgresp_t add_resp;
					add_resp.result = ret;
					strcpy(add_resp.desc,(ret == 0)?"Success":"Failed");
					send_msg(sockfd,RESPONSE,ADDPERSON,&add_resp,sizeof(add_resp));
					break;
				}
				case UPDATEPERSON:
				{
					update_person_request_t upd;
					memset(&upd,0,sizeof(upd));
					memcpy(&upd,buf+sizeof(head),sizeof(upd));
					ret = update_person_handler(&upd);
					msgresp_t upd_resp;
					upd_resp.result = ret;
					strcpy(upd_resp.desc,(ret == 0)?"Success":"Failed");
					send_msg(sockfd,RESPONSE,UPDATEPERSON,&upd_resp,sizeof(upd_resp));
					break;
				}
				case DELPERSON:
				{
					delete_person_request_t del;
					memset(&del,0,sizeof(del));
					memcpy(&del,buf+sizeof(head),sizeof(del));
					ret = delete_person_handler(&del);
					msgresp_t del_resp;
					del_resp.result = ret;
					strcpy(del_resp.desc,(ret == 0)?"Success":"Failed");
					send_msg(sockfd,RESPONSE,DELPERSON,&del_resp,sizeof(del_resp));
					break;
				}
				case CLRPERSON:
				{
					ret = clear_person_handler();
					msgresp_t clr_resp;
					clr_resp.result = ret;
					strcpy(clr_resp.desc,(ret == 0)?"Success":"Failed");
					send_msg(sockfd,RESPONSE,CLRPERSON,&clr_resp,sizeof(clr_resp));
					break;
				}
				default:
				{
					printf("invalid request datatype\n");
					break;
				}
			}
			break;
		}
		case RESPONSE:
		{
			switch(datatype)
			{
			case REGISTER:
				{
					msgresp_t resp;
					memcpy(&resp,buf+sizeof(head),sizeof(resp));
					if(resp.result == 0)
					{
						register_response_t *reg_data = (register_response_t *)resp.data;
						memcpy(g_uuid, reg_data->uuid, sizeof(g_uuid));
						memcpy(g_passwd, reg_data->passwd, sizeof(g_passwd));
						g_register = 1; 
						printf("Register success uuid:%s passwd:%s\n",g_uuid,g_passwd);
					}else
					{
						printf("Register failed\n");
					}
					break;
				}
			case LOGIN:
				{
					msgresp_t resp;
					memcpy(&resp, buf + sizeof(head), sizeof(resp));
					if(resp.result == 0) {
						g_login = 1;
						printf("Login successful\n");
					} else {
						printf("Login failed: %s\n", resp.desc);
						g_register = 0; 
					}
					break;
				}
			default:
				{
					printf("invalid response datatype\n");
					break;
				}
			}
			break;
		}
		default:
		{
			printf("invalid server msgtype,try again\n");
			break;
		}
	}
	return 0;
}

/********************************************************************
 *函数名：int register_handler(register_request_t *reg,char *uuid,char *passwd)
 *功能：处理注册请求,生成唯一设备id和密钥
 *参数：
 * reg:注册请求数据
 * uuid:出参，设备ID
 * passwd:出参，设备密钥
 *返回值：成功返回0，失败返回-1
********************************************************************/
int register_handler(register_request_t *reg,char *uuid,char *passwd)
{
	sqlite3 *db;
	int ret;
	char *errmsg;

	if (sqlite3_open("devices.db", &db) != SQLITE_OK) {
		printf("sqlite3_open failed\n");
		return -1;
	}

	srand(time(NULL));
	snprintf(uuid, 31, "%08x%08x%08x%08x", rand(), rand(), rand(), rand());
	snprintf(passwd, 15, "%08x%08x", rand(), rand());

	char sql[512];
	snprintf(sql, sizeof(sql), 
			"INSERT OR REPLACE INTO devices (serial, mac, uuid, passwd, type, register_time) "
			"VALUES ('%s', '%s', '%s', '%s', '%s', %ld);",
			reg->serial, reg->mac, uuid, passwd, reg->type, time(NULL));

	ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
	if(ret != SQLITE_OK) {
		printf("sqlite3_exec failed: %s\n", errmsg);
		sqlite3_free(errmsg);
		sqlite3_close(db);
		return -1;
	}

	sqlite3_close(db);
	return 0;
}

/********************************************************************
 *函数名：int login_handler(login_request_t *login)
 *功能：处理登录请求，验证设备UUID
 *参数：
 * login: 登录请求结构体指针
 *返回值：成功返回0，失败返回-1
********************************************************************/
int login_handler(login_request_t *login)
{
	sqlite3 *db;
	char *sql = "select * from devices where uuid = ?";
	sqlite3_stmt *stmt;

	if (sqlite3_open("devices.db", &db) != SQLITE_OK) {
		printf("sqlite3_open failed\n");
		return -1;
	}

	int ret = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
	if(ret != SQLITE_OK) {
		printf("sqlite3_prepare_failed\n");
		sqlite3_close(db);
		return -1;
	}

	sqlite3_bind_text(stmt, 1, login->uuid, -1, SQLITE_STATIC);

	ret = sqlite3_step(stmt);
	if(ret != SQLITE_ROW) {
		printf("device not found\n");
		sqlite3_finalize(stmt);
		sqlite3_close(db);
		return -1;
	}

	sqlite3_finalize(stmt);
	sqlite3_close(db);
	return 0;
	
}

/********************************************************************
 *函数名：int distribute_person_handler(add_person_request_t *person)
 *功能：处理下发人员请求，将人员信息插入到设备的persons数据库
 *参数：
 * person: 人员信息结构体指针
 *返回值：成功返回0，失败返回-1
********************************************************************/
int distribute_person_handler(add_person_request_t *person)
{
	int ret;
	sqlite3 *db;
	char *errmsg;
	ret = sqlite3_open("persons.db",&db);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open persons db failed\n");
		return -1;
	}
	char sql[512];
	snprintf(sql, sizeof(sql), 
			"INSERT INTO persons (personId, personCode, name, type, idNum, icNum, passNum, passPeriod) "
			"VALUES ('%s', '%s', '%s', %d, '%s', '%s', %d, '%s');",
			person->personId, person->personCode, person->name, person->type, 
			person->idNum, person->icNum, person->passNum, person->passPeriod);
	ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_exec failed : %s\n",errmsg);
		sqlite3_free(errmsg);
		sqlite3_close(db);
		return -1;
	}

	printf("Person distributed: %s (%s)\n", person->name, person->personId);
	sqlite3_close(db);
	return 0;
}

/********************************************************************
 *函数名：int add_person_handler(add_person_request_t *person)
 *功能：处理添加人员请求，将人员信息插入到服务器的server_persons数据库
 *参数：
 * person: 人员信息结构体指针
 *返回值：成功返回0，失败返回-1
********************************************************************/
int add_person_handler(add_person_request_t *person)
{
	int ret;
	sqlite3 *db;
	char *errmsg;
	ret = sqlite3_open("server_persons.db",&db);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open persons db failed\n");
		return -1;
	}
	char sql[512];
	snprintf(sql, sizeof(sql), 
			"INSERT INTO persons (personId, personCode, name, type, idNum, icNum, passNum, passPeriod) "
			"VALUES ('%s', '%s', '%s', %d, '%s', '%s', %d, '%s');",
			person->personId, person->personCode, person->name, person->type, 
			person->idNum, person->icNum, person->passNum, person->passPeriod);
	ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_exec failed : %s\n",errmsg);
		sqlite3_free(errmsg);
		sqlite3_close(db);
		return -1;
	}
	sqlite3_close(db);
	return 0;

	printf("Person added: %s (%s)\n", person->name, person->personId);
	return 0;
}

/********************************************************************
 *函数名：int update_person_handler(update_person_request_t *person)
 *功能：处理更新人员请求，更新persons数据库中的人员信息
 *参数：
 * person: 人员信息结构体指针
 *返回值：成功返回0，失败返回-1
********************************************************************/
int update_person_handler(update_person_request_t *person)
{
	char *sql = "UPDATE persons SET personCode = ?, name = ?, type = ?, "
		"idNum = ?, icNum = ?, passNum = ?, passPeriod = ? "
		"WHERE personId = ?";
	sqlite3_stmt *stmt;
	sqlite3 *db;
	if (sqlite3_open("persons.db", &db) != SQLITE_OK) {
		printf("sqlite3_open failed\n");
		return -1;
	}

	int ret = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
	if(ret != SQLITE_OK) {
		printf("sqlite3_prepare_v2 failed\n");
		return -1;
	}

	sqlite3_bind_text(stmt, 1, person->personCode, -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt, 2, person->name, -1, SQLITE_STATIC);
	sqlite3_bind_int(stmt, 3, person->type);
	sqlite3_bind_text(stmt, 4, person->idNum, -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt, 5, person->icNum, -1, SQLITE_STATIC);
	sqlite3_bind_int(stmt, 6, person->passNum);
	sqlite3_bind_text(stmt, 7, person->passPeriod, -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt, 8, person->personId, -1, SQLITE_STATIC);

	ret = sqlite3_step(stmt);
	sqlite3_finalize(stmt);

	if(ret != SQLITE_DONE) {
		printf("update failed\n");
		return -1;
	}

	printf("Person updated: %s\n", person->personId);
	sqlite3_close(db);
	return 0;
}

/********************************************************************
 *函数名：int delete_person_handler(delete_person_request_t *del_req)
 *功能：处理删除人员请求，从server_persons数据库删除指定人员
 *参数：
 * del_req: 删除请求结构体指针
 *返回值：成功返回0，失败返回-1     
********************************************************************/
int delete_person_handler(delete_person_request_t *del_req)
{
	char *sql = "DELETE FROM persons WHERE personId = ?";
	sqlite3_stmt *stmt;
	sqlite3 *db;
	if (sqlite3_open("server_persons.db", &db) != SQLITE_OK) {
		printf("sqlite3_open failed\n");
		return -1;
	}

	int ret = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
	if(ret != SQLITE_OK) {
		return -1;
	}

	sqlite3_bind_text(stmt, 1, del_req->idSet, -1, SQLITE_STATIC);

	ret = sqlite3_step(stmt);
	sqlite3_finalize(stmt);

	if(ret != SQLITE_DONE) {
		printf("delete failed\n");
		return -1;
	}

	printf("Person deleted: %s\n", del_req->idSet);
	sqlite3_close(db);
	return 0;
}


/********************************************************************
 *函数名：int database_init()
 *功能：初始化数据库，创建必要的表和数据库文件
 *参数：无
 *返回值：成功返回0，失败返回-1
********************************************************************/
int database_init()
{
	sqlite3 *db;

	int ret = sqlite3_open("server_persons.db",&db);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open server_persons db failed\n");
		return -1;
	}

	char *server_persons_sql = "CREATE TABLE IF NOT EXISTS persons ("
		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
		"personId TEXT UNIQUE NOT NULL, "
		"personCode TEXT NOT NULL, "
		"name TEXT NOT NULL, "
		"type INTEGER NOT NULL, "
		"idNum TEXT, "
		"icNum TEXT, "
		"passNum INTEGER, "
		"passPeriod TEXT);";
	ret = sqlite3_exec(db,server_persons_sql,NULL,NULL,NULL);
	if(ret != 0)
	{
		printf("sqlite3_exec server_persons dbfailed\n");
		sqlite3_close(db);
		return -1;
	}
	sqlite3_close(db);


	ret = sqlite3_open("devices.db",&db);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open devices db failed\n");
		return -1;
	}

	char *device_sql = "CREATE TABLE IF NOT EXISTS devices ("
		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
		"serial TEXT UNIQUE NOT NULL, "
		"mac TEXT NOT NULL, "
		"uuid TEXT UNIQUE NOT NULL, "
		"passwd TEXT NOT NULL, "
		"type TEXT NOT NULL, "
		"register_time INTEGER);";
	ret = sqlite3_exec(db,device_sql,NULL,NULL,NULL);
	if(ret != 0)
	{
		printf("sqlite3_exec devices dbfailed\n");
		sqlite3_close(db);
		return -1;
	}
	sqlite3_close(db);

	ret = sqlite3_open("persons.db",&db);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open persons db failed\n");
		return -1;
	}

	char *person_sql = "CREATE TABLE IF NOT EXISTS persons ("
		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
		"personId TEXT UNIQUE NOT NULL, "
		"personCode TEXT NOT NULL, "
		"name TEXT NOT NULL, "
		"type INTEGER NOT NULL, "
		"idNum TEXT, "
		"icNum TEXT, "
		"passNum INTEGER, "
		"passPeriod TEXT);";
	ret = sqlite3_exec(db,person_sql,NULL,NULL,NULL);
	if(ret != 0)
	{
		printf("sqlite3_exec person db failed\n");
		sqlite3_close(db);
		return -1;
	}
	sqlite3_close(db);
	printf("Database init success\n");
	return 0;
}

/********************************************************************
 *函数名：int generate_signature(char *str1, char *str2, char *str3, char output)
 *功能：生成MD5签名
 *参数：
 * str1, str2, str3: 需要签名的字符串
 * output: 输出签名缓冲区
 *返回值：成功返回0  
********************************************************************/
int generate_signature(char *str1,char *str2,char *str3,char *output)
{
	char sign_str[256];
	char *key = "P3K0eikSRSJHliME";
	snprintf(sign_str, sizeof(sign_str), "%s%s%s%s", str1, str2, str3,key);

	// 计算MD5
	unsigned char digest[MD5_DIGEST_LENGTH];
	MD5_CTX context;

	MD5_Init(&context);
	MD5_Update(&context, sign_str, strlen(sign_str));
	MD5_Final(digest, &context);

	// 转换为十六进制字符串
	for (int i = 0; i <MD5_DIGEST_LENGTH; i++) {
		sprintf(&output[i*2],"%02x", (unsigned int)digest[i]);
	}

	output[MD5_DIGEST_LENGTH* 2] = '\0';
	return 0;
}

/********************************************************************
 *函数名：int clear_person_handler()
 *功能：清空server_persons数据库中的所有人员
 *参数：无
 *返回值：成功返回0，失败返回-1     
********************************************************************/
int clear_person_handler()
{
	char *sql = "DELETE FROM persons";
	sqlite3 *db;
	char *errmsg;
	int ret = sqlite3_open("server_persons.db",&db);
	if(ret != SQLITE_OK)
	{
		printf("sqlite3_open server_persons db failed\n");
		return -1;
	}

	ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
	if(ret != SQLITE_OK) {
		printf("sqlite3_exec failed: %s\n",errmsg);
		sqlite3_free(errmsg);
		sqlite3_close(db);
		return -1;
	}

	printf("All persons cleared\n");
	sqlite3_close(db);
	return 0;
}

/********************************************************************
 *函数名：int distribute_all_persons()
 *功能：下发server_persons数据库中所有人员信息到persons数据库
 *参数：无
 *返回值：成功返回0，失败返回-1     
 ********************************************************************/
int distribute_all_persons()
{
	sqlite3 *db;
	sqlite3_stmt *stmt;
	int ret;

	if (sqlite3_open("server_persons.db", &db) != SQLITE_OK) {
		printf("sqlite3_open failed\n");
		return -1;
	}

	char *sql = "SELECT * FROM persons";
	ret = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
	if(ret != SQLITE_OK) {
		printf("sqlite3_prepare_v2 failed\n");
		sqlite3_close(db);
		return -1;
	}

	while(sqlite3_step(stmt) == SQLITE_ROW) {
		add_person_request_t person;
		memset(&person, 0, sizeof(person));
		strncpy(person.personId, (const char*)sqlite3_column_text(stmt, 1), sizeof(person.personId)-1);
		strncpy(person.personCode, (const char*)sqlite3_column_text(stmt, 2), sizeof(person.personCode)-1);
		strncpy(person.name, (const char*)sqlite3_column_text(stmt, 3), sizeof(person.name)-1);
		person.type = sqlite3_column_int(stmt, 4);
		strncpy(person.idNum, (const char*)sqlite3_column_text(stmt, 5), sizeof(person.idNum)-1);
		strncpy(person.icNum, (const char*)sqlite3_column_text(stmt, 6), sizeof(person.icNum)-1);
		person.passNum = sqlite3_column_int(stmt, 7);
		strncpy(person.passPeriod, (const char*)sqlite3_column_text(stmt, 8), sizeof(person.passPeriod)-1);
		distribute_person_handler(&person);
	}
	printf("Finished distributing all persons.\n");

	sqlite3_finalize(stmt);
	sqlite3_close(db);
	return 0;
}
